// main.go
package main

import (
	"context"
	"log"
	"net/http"
	"net/http/httputil"
	"net/url"

	"github.com/gin-gonic/gin"
	"go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin"
	"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
	"go.opentelemetry.io/otel/propagation"
	"go.opentelemetry.io/otel/sdk/resource"
	"go.opentelemetry.io/otel/sdk/trace"
	semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
)

func main() {
	log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)

	tp := initTracer()
	defer tp.Shutdown(context.Background())

	r := gin.Default()

	// 1.自动追踪 HTTP 请求
	r.Use(otelgin.Middleware("gate-way-service"))

	// 2. JWT 认证中间件
	r.Use(func(c *gin.Context) {
		token := c.GetHeader("Authorization")
		if token != "valid-token" {
			// c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"})
			log.Println("Unauthorized")
		} else {
			log.Println("Authorized")
		}
	})

	// 路由转发（类似 Spring Cloud Gateway 的 Route）
	r.GET("/hello", ProxyHandler)

	r.GET("/proxy", SelefDefineProxyHandler)

	// 添加 health 路由
	r.GET("/health", func(c *gin.Context) {
		// 添加实际健康检查逻辑（如数据库连接测试）
		c.JSON(200, gin.H{"status": "healthy"})
	})

	r.GET("/call-third-party-api", CallThirdPartyAPI)

	r.Run(":8088")
}

func initTracer() *trace.TracerProvider {
	// 1. 配置 OTLP/HTTP 导出器（指向 Jaeger 的 OTLP 端口）
	exporter, err := otlptracehttp.New(context.Background(),
		otlptracehttp.WithEndpoint("10.120.137.235:4318"), // OTLP HTTP 端口
		otlptracehttp.WithInsecure(),                      // 非 TLS（生产环境应启用）
	)
	if err != nil {
		log.Fatalf("OTLP 导出器创建失败: %v", err)
	}

	// 2. 配置资源（标识服务）
	res, err := resource.New(context.Background(),
		resource.WithAttributes(
			semconv.ServiceNameKey.String("gate-way-service"),
		),
	)
	if err != nil {
		log.Fatalf("资源创建失败: %v", err)
	}

	// 3. 创建 Tracer Provider
	tp := trace.NewTracerProvider(
		trace.WithBatcher(exporter),
		trace.WithResource(res),
	)
	otel.SetTracerProvider(tp)

	// 设置传播器以支持W3C Trace Context；该标准用来规范分布式系统中请求链路的追踪上下文传递方式。它的核心作用是解决跨服务、跨系统的请求跟踪问题
	otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(
		propagation.TraceContext{},
		propagation.Baggage{},
	))

	return tp
}

// ProxyHandler  转发示例接口
// @Summary      返回欢迎信息
// @Description  返回一个简单的欢迎字符串
// @Accept       json
// @Produce      json
// @Success      200  {string}  string  "Hello, World!"
// @Router       /hello [get]
func ProxyHandler(c *gin.Context) {
	// 默认会把请求路径hello添加在http://10.120.137.235:8080/api/v1/末尾
	target, _ := url.Parse("http://10.120.137.235:8080/api/v1")
	proxy := httputil.NewSingleHostReverseProxy(target)
	proxy.ServeHTTP(c.Writer, c.Request)
}

func CallThirdPartyAPI(c *gin.Context) {
	// 调用第三方 API 的逻辑
	// 创建带追踪的 HTTP 客户端
	client := http.Client{Transport: otelhttp.NewTransport(http.DefaultTransport)}
	// 构造请求（注入追踪上下文）
	req, err := http.NewRequestWithContext(c.Request.Context(), "GET", "http://10.120.137.235:8080/api/v1/hello", nil)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	// 发送请求
	resp, err := client.Do(req)
	if err != nil {
		c.JSON(http.StatusBadGateway, gin.H{"error": err.Error()})
		return
	}
	defer resp.Body.Close()

	c.JSON(http.StatusOK, gin.H{"message": "success"})
}

func SelefDefineProxyHandler(c *gin.Context) {
	target, _ := url.Parse("http://10.120.137.235:8080/api/v1/hello")
	proxy := httputil.NewSingleHostReverseProxy(target)

	// 自定义请求路径
	proxy.Director = func(req *http.Request) {
		req.URL.Scheme = target.Scheme
		req.URL.Host = target.Host
		req.URL.Path = target.Path // 直接使用目标路径，忽略原始路径
		// req.URL.Path = "/api/v1/hello" // 或者硬编码新路径
	}

	proxy.ServeHTTP(c.Writer, c.Request)
}
